using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System.Configuration;

namespace FreeLancer.HRB.Core.Services
{
  /// <summary>
  /// Logger utility.
  /// </summary>
  public class LoggingService
  {
    /// <summary>
    /// Debug property. Default value is true.
    /// </summary>
    public static bool IsDebug = true;

    /// <summary>
    /// Default Category is "General"
    /// </summary>
    public const string DefaultCategory = "General";

    /// <summary>
    /// Log Error 
    /// </summary>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="properties"></param>
    public static void LogError(string message, Exception ex, string category, IDictionary<string, object> properties)
    {
      Log(message, ex, category, properties, System.Diagnostics.TraceEventType.Error);
    }

    /// <summary>
    /// Log Warning
    /// </summary>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="properties"></param>
    public static void LogWarning(string message, Exception ex, string category, IDictionary<string, object> properties)
    {
      Log(message, ex, category, properties, System.Diagnostics.TraceEventType.Warning);
    }

    /// <summary>
    /// Log Information
    /// </summary>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="properties"></param>
    public static void LogInformation(string message, Exception ex, string category, IDictionary<string, object> properties)
    {
      Log(message, ex, category, properties, System.Diagnostics.TraceEventType.Information);
    }

    /// <summary>
    /// Log Critical
    /// </summary>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="properties"></param>
    public static void LogCritical(string message, Exception ex, string category, IDictionary<string, object> properties)
    {
      Log(message, ex, category, properties, System.Diagnostics.TraceEventType.Critical);
    }

    /// <summary>
    /// Log Verbose
    /// </summary>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="properties"></param>
    public static void LogVerbose(string message, Exception ex, string category, IDictionary<string, object> properties)
    {
      if (IsDebug)
        Log(message, ex, category, properties, System.Diagnostics.TraceEventType.Verbose);
    }

    /// <summary>
    /// Log Error
    /// </summary>
    /// <param name="title"></param>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="sendEmail"></param>
    public static void LogError(string title, string message, Exception ex, string category, bool sendEmail)
    {
      Log(title, message, ex, category, null, System.Diagnostics.TraceEventType.Error, sendEmail);
    }

    /// <summary>
    /// Log Warning
    /// </summary>
    /// <param name="title"></param>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="sendEmail"></param>
    public static void LogWarning(string title, string message, Exception ex, string category, bool sendEmail)
    {
      Log(title, message, ex, category, null, System.Diagnostics.TraceEventType.Warning, sendEmail);
    }

    /// <summary>
    /// Log Information
    /// </summary>
    /// <param name="title"></param>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="sendEmail"></param>
    public static void LogInformation(string title, string message, Exception ex, string category, bool sendEmail)
    {
      Log(title, message, ex, category, null, System.Diagnostics.TraceEventType.Information, sendEmail);
    }

    /// <summary>
    /// Log Critical
    /// </summary>
    /// <param name="title"></param>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="sendEmail"></param>
    public static void LogCritical(string title, string message, Exception ex, string category, bool sendEmail)
    {
      Log(title, message, ex, category, null, System.Diagnostics.TraceEventType.Critical, sendEmail);
    }

    /// <summary>
    /// Log Verbose
    /// </summary>
    /// <param name="title"></param>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="sendEmail"></param>
    public static void LogVerbose(string title, string message, Exception ex, string category, bool sendEmail)
    {
      Log(title, message, ex, category, null, System.Diagnostics.TraceEventType.Verbose, sendEmail);
    }

    /// <summary>
    /// General Log 
    /// </summary>
    /// <param name="title"></param>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="properties"></param>
    /// <param name="traceEventType"></param>
    /// <param name="sendEmail"></param>
    public static void Log(string title, string message, Exception ex, string category, IDictionary<string, object> properties,
      System.Diagnostics.TraceEventType traceEventType, bool sendEmail)
    {
      LogEntry log = new LogEntry();
      log.Title = title;
      log.Message = message;
      if (ex != null)
        log.AddErrorMessage(ex.ToString());
      if (!string.IsNullOrEmpty(log.ErrorMessages))
        log.Message += " : " + log.ErrorMessages;
      log.Categories.Add(category.ToString());
      log.Severity = traceEventType;
      log.ExtendedProperties = properties;
      Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(log);

      if (sendEmail)
        SendLog(log);
    }

    /// <summary>
    /// General Log 
    /// </summary>
    /// <param name="message"></param>
    /// <param name="ex"></param>
    /// <param name="category"></param>
    /// <param name="properties"></param>
    /// <param name="traceEventType"></param>
    public static void Log(string message, Exception ex, string category, IDictionary<string, object> properties,
      System.Diagnostics.TraceEventType traceEventType)
    {
      Log(string.Empty, message, ex, category, properties, traceEventType, false);
    }

    /// <summary>
    /// Send log to e-mail.
    /// </summary>
    /// <param name="logEntry">Log entry.</param>
    public static void SendLog(LogEntry logEntry)
    {
      StringBuilder builder = new StringBuilder();
      builder.Append("------------------------------<br/>");
      builder.Append("Title: " + logEntry.Title + "<br/>");
      builder.Append("Time Stamp: " + logEntry.TimeStampString + "<br/>");
      builder.Append("=====<br/>");
      builder.Append("Message: <br/>");
      builder.Append(logEntry.Message + "<br/>");
      builder.Append("=====<br/>");
      builder.Append("Error Message: <br/>");
      builder.Append(logEntry.ErrorMessages + "<br/>");
      builder.Append("------------------------------<br/>");

      string sendTo = ConfigurationManager.AppSettings["Logging.EmailAddress"];
      string subject = ConfigurationManager.AppSettings["Logging.EmailSubject"];
      string message = builder.ToString();

      subject += logEntry.Title;

      EmailService.SendMailAsync(sendTo, subject, message);
    }
  }
}
